package com.example.udpscreen.runnables;

import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.DatagramPacket;
import java.net.InetAddress;

import com.example.udpscreen.enums.UdpSocketDataType;
import com.example.udpscreen.servers.BaseSocket;
import com.example.udpscreen.utils.Convert;
import com.example.udpscreen.utils.FileUtil;

import android.graphics.Bitmap;
import android.util.Log;

public class MonitorRunnable implements Runnable {

	private final static byte CMD_DATA = 0x0A, CMD_DATA_END = 0x10, CMD_DATA_BEGIN = 0x11, CMD_FATAL = 0x1F;

	private final static byte ERR_NO_SU = 0x10, ERR_RUNTIME = 0x11;

	private final static int DATA_LEN = 5 * 1024;

	private BaseSocket mSocket;
	private InetAddress mRemoteAddress;
	private int mRemotePort;

	public MonitorRunnable(BaseSocket socket, InetAddress address, int port) {
		this.mSocket = socket;
		this.mRemoteAddress = address;
		this.mRemotePort = port;
	}

	@Override
	public void run() {
		// 截图保存文件
		String path = GetandSaveCurrentImage();

		if (path != null) {
			// 循环发文件
			File file = new File(path);
			if (file.exists()) {
				ByteArrayOutputStream baos = null;
				ByteArrayInputStream input_stream = null;
				try {
					Bitmap bitmap = FileUtil.readBitMap(FileUtil.MonitorFileTemp);
					baos = new ByteArrayOutputStream();
					bitmap.compress(Bitmap.CompressFormat.PNG, 100, baos);

					input_stream = new ByteArrayInputStream(baos.toByteArray());
					baos.close();

					int file_size = input_stream.available();
					sendBeginFlag(file_size);
					try {
						Thread.sleep(100);
					} catch (InterruptedException e1) {
						e1.printStackTrace();
					}
					// FileInputStream input_stream=new FileInputStream(file);
					byte[] send_bytes = new byte[DATA_LEN + 10];
					send_bytes[0] = UdpSocketDataType.MONITOR;
					send_bytes[1] = (byte) (255 - UdpSocketDataType.MONITOR);
					send_bytes[2] = CMD_DATA;
					int total_send = 0;
					int len = 0;
					while ((len = input_stream.read(send_bytes, 10, send_bytes.length - 10)) > 0) {

						byte[] index_bytes = Convert.int2Bytes(total_send);
						System.arraycopy(index_bytes, 0, send_bytes, 3, index_bytes.length);
						DatagramPacket packet = new DatagramPacket(send_bytes, len + 10, mRemoteAddress, mRemotePort);
						try {
							Thread.sleep(3);
							mSocket.sendDatagramPacket(packet);
						} catch (Exception e) {
							e.printStackTrace();
							sendFatal(ERR_RUNTIME);

						}
						total_send += len;

					}
					// 发送结束标识
					sendEndFlag();

				} catch (Exception e) {
					e.printStackTrace();
					sendFatal(ERR_RUNTIME);
				} finally {

					try {
						if (baos != null)
							baos.close();

					} catch (IOException e) {
						e.printStackTrace();
					}
					try {
						if (input_stream != null)
							input_stream.close();
					} catch (IOException e) {
						e.printStackTrace();
					}
				}
			}
		} else {
			sendFatal(ERR_NO_SU);
		}

	}

	private void sendFatal(byte err_code) {
		byte[] bytes = new byte[10];
		bytes[0] = UdpSocketDataType.MONITOR;
		bytes[1] = (byte) (255 - UdpSocketDataType.MONITOR);
		bytes[2] = CMD_FATAL;
		bytes[3] = err_code;
		DatagramPacket packet = new DatagramPacket(bytes, bytes.length, mRemoteAddress, mRemotePort);
		try {
			Thread.sleep(1);
			mSocket.sendDatagramPacket(packet);
			System.out.println("sendDataBegin");
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	private void sendBeginFlag(int file_size) {
		byte[] begin_bytes = new byte[10];
		begin_bytes[0] = UdpSocketDataType.MONITOR;
		begin_bytes[1] = (byte) (255 - UdpSocketDataType.MONITOR);
		begin_bytes[2] = CMD_DATA_BEGIN;
		byte[] len_bytes = Convert.int2Bytes(file_size);
		System.arraycopy(len_bytes, 0, begin_bytes, 3, len_bytes.length);
		DatagramPacket packet = new DatagramPacket(begin_bytes, begin_bytes.length, mRemoteAddress, mRemotePort);
		try {
			Thread.sleep(1);
			mSocket.sendDatagramPacket(packet);
			System.out.println("sendDataBegin");
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	private void sendEndFlag() {
		byte[] end_bytes = new byte[10];
		end_bytes[0] = UdpSocketDataType.MONITOR;
		end_bytes[1] = (byte) (255 - UdpSocketDataType.MONITOR);
		end_bytes[2] = CMD_DATA_END;
		DatagramPacket packet = new DatagramPacket(end_bytes, end_bytes.length, mRemoteAddress, mRemotePort);
		try {
			Thread.sleep(1);
			mSocket.sendDatagramPacket(packet);
			System.out.println("sendDataEnd");
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	private String GetandSaveCurrentImage() {
		String path = FileUtil.MonitorFileTemp;
		String cmd = "screencap -p " + path + " \n";
		Process process = null;
		DataOutputStream os = null;
		BufferedReader br = null;
		StringBuilder sb = null;
		try {
			process = Runtime.getRuntime().exec("su \n");
			os = new DataOutputStream(process.getOutputStream());
			os.writeBytes(cmd + "\n");
			os.writeBytes("exit\n");
			br = new BufferedReader(new InputStreamReader(process.getInputStream()));

			sb = new StringBuilder();
			String temp = null;
			while ((temp = br.readLine()) != null) {
				sb.append(temp + "\n");
				Log.e("TMS", "temp==" + temp);
				if ("Success".equalsIgnoreCase(temp)) {
					Log.e("TMS", "----------" + sb.toString());
					return path;
				}
			}
			process.waitFor();
		} catch (Exception e) {
			Log.e("TMS", "截图保存异常：" + e.getMessage());
			return null;
		} finally {
			try {
				if (os != null) {
					os.flush();
					os.close();
				}
				if (br != null) {
					br.close();
				}
				process.destroy();
			} catch (Exception e) {
				return null;
			}
		}
		return path;
	}

}
